package com.xxcloud.search.service.note.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import com.xxcloud.common.search.LocalSortOrder;
import com.xxcloud.common.search.RangeBean;
import com.xxcloud.search.api.bean.note.NoteApiParameter;
import com.xxcloud.search.api.bean.note.NoteItem;
import com.xxcloud.search.api.bean.note.NoteSortType;
import com.xxcloud.search.model.note.NoteIndex;
import com.xxcloud.search.model.note.NoteModel;

/**
 * Created by chenbingwen on 19/11/5.
 */
public class AbstractNoteSearchService {

    protected BoolQueryBuilder buildBoolQuery(NoteApiParameter parameter) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 进行分词检索
        String keyword = parameter.getKeyword();
        if (StringUtils.isNotBlank(keyword)) {
            boolQueryBuilder.must(QueryBuilders.matchQuery(NoteIndex.Filed.CONTENT, keyword));
        }
        // 字符串模糊查询
        String title = parameter.getTitle();
        if (StringUtils.isNotBlank(title)) {
            boolQueryBuilder.must(QueryBuilders.matchQuery(NoteIndex.Filed.TITLE, title));
        }
        return boolQueryBuilder;
    }

    // 构建filterQuery，无需进行打分计算的字段搜索放filter中
    protected BoolQueryBuilder buildFilterQuery(NoteApiParameter parameter) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // id
        List<Long> ids = parameter.getIds();
        if (CollectionUtils.isNotEmpty(ids)) {
            boolQueryBuilder.must(QueryBuilders.termsQuery(NoteIndex.Filed.ID, ids));
        }
        // 区间
        RangeBean createTimeRange = parameter.getCreateTimeRange();
        if (createTimeRange != null) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery(NoteIndex.Filed.CREATE_TIME).lt(createTimeRange.getMin()).gte(createTimeRange.getMax()));
        }
        return boolQueryBuilder;
    }

    protected FieldSortBuilder buildFieldSortBuilder(NoteApiParameter parameter) {
        String sortField = null;
        SortOrder sortOrder = null;
        NoteSortType sortType = parameter.getSortType();
        if (sortType != null) {
            switch (sortType) {
                case CREATE_TIME:
                    sortField = NoteIndex.Filed.CREATE_TIME;
                    break;
                case UPDATE_TIME:
                    sortField = NoteIndex.Filed.UPDATE_TIME;
                    break;
                default:
                    sortField = NoteIndex.Filed.CREATE_TIME;
                    break;
            }
        }
        LocalSortOrder localSortOrder = parameter.getLocalSortOrder();
        if (localSortOrder != null) {
            if (LocalSortOrder.DESC == localSortOrder) {
                sortOrder = SortOrder.DESC;
            } else {
                sortOrder = SortOrder.ASC;
            }
        }
        FieldSortBuilder sortBuilder = null;
        if (StringUtils.isNotBlank(sortField) && sortOrder != null) {
            sortBuilder = SortBuilders.fieldSort(sortField).order(sortOrder);
        }
        return sortBuilder;
    }

    protected PageRequest buildPageRequest(NoteApiParameter parameter) {
        return PageRequest.of(parameter.getFirst(), parameter.getMax());
    }

    protected List<String> analysisKeyword(String keyword) {
        return new ArrayList<>();
    }

    protected List<NoteItem> convert2NoteItems(List<NoteModel> noteModels) {
        if (CollectionUtils.isEmpty(noteModels)) {
            return Collections.emptyList();
        }
        List<NoteItem> result = new ArrayList<>();

        noteModels.stream().forEach(noteModel -> {
            NoteItem noteItem = new NoteItem();
            noteItem.setId(noteModel.getId());
            result.add(noteItem);
        });
        return result;
    }

    protected String buildDSLQuery(QueryBuilder queryBuilder) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        return searchSourceBuilder.toString();
    }
}
